import { staticPosType } from "./interface";
import Feature from "./features";
import { IRelativePos } from "@/Interface";
import { gridConstant } from "./constant";
import { UL } from "./utils";

class GridMain {
  features: Feature[] = [];
  domEle: HTMLCanvasElement;
  scale: number = 10
  ctx: CanvasRenderingContext2D;
  staticPos: staticPosType = { x: 350, y: 300 };
  constructor(csv: HTMLCanvasElement) {
    this.domEle = csv;
    this.ctx = csv.getContext("2d") || new CanvasRenderingContext2D();
  }

  draw(loop=true) {
    this.ctx.clearRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height);
    this.drawFeature();
    this.initEvent();
    window.requestAnimationFrame(() => {this.draw(loop)});
  }

  initEvent() {
    this.domEle.addEventListener("contextmenu", (e) => {
      e.preventDefault();
    });
    document.addEventListener("mousedown", (ev) => {
      const lastMousePos = { x: 0, y: 0 };
      let mouseMv = (e: any) => {
        e;
      };
      if (ev.buttons == 2) {
        // 2 表示鼠标右键
        mouseMv = (e) => {
          const { x: mouseX, y: mouseY } = UL.getMousePos(this.domEle, e);
          // console.log(mouseX, mouseY)
          if (lastMousePos.x && lastMousePos.y) {
            this.translate(mouseX - lastMousePos.x, mouseY - lastMousePos.y);
          }
          lastMousePos.x = mouseX;
          lastMousePos.y = mouseY;
        };
      }
      const mouseUp = () => {
        document.removeEventListener("mousemove", mouseMv);
        document.removeEventListener("mouseup", mouseUp);
      };
      document.addEventListener("mousemove", mouseMv);
      document.addEventListener("mouseup", mouseUp);
    });
  }

  translate(offsetX: number = 0, offsetY: number = 0) {
    this.staticPos.x += offsetX;
    this.staticPos.y += offsetY;
  }

  getRatioSize(size: number, isPixelLen = false): number {
    if (isPixelLen) {
        return size;
    } else {
        return size * this.scale;
    }
}

  // 将相对坐标转换为像素坐标
  getPixelPos(point: IRelativePos) {
    return {
      x: (this.scale) * (point.x / gridConstant.SIZE) + this.staticPos.x,
      y: (this.scale) * (point.y / gridConstant.SIZE) + this.staticPos.y,
    };
  }

  drawFeature(features: Feature[] = this.features) {
    features.forEach((feature) => {
      const points = feature.pointArr.map((p) => this.getPixelPos(p));
      feature.draw(this.ctx, points);
    });
  }

  addFeature(feature: Feature) {
    this.features.push(feature);
  }
}

export default GridMain;
